package myLearnjdk.jdk.util.concurrent;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 利用本地缓存实现一个心跳超时判断机制----非分布式
 * @author yangcheng  
 * @date 2019年8月23日  
 * @version V1.0
 */
public class TestScheduleTask {
	static final AtomicInteger val = new AtomicInteger(1);
	/**
	 * 缓存所有循环定时任务对应的Future---用于关闭schedule队列中的任务
	 */
	static ConcurrentHashMap<String, Future> futureCache = new ConcurrentHashMap<>();
	/**
	 * 缓存所有task
	 */
	static ConcurrentHashMap<String, Runnable> taskCache = new ConcurrentHashMap<>();
	public static void main(String[] args) throws InterruptedException {
		ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1);
		
		
		for(int i = 0 ; i <10 ; i++){
			
			/**
			 * 初始化定时任务   3000毫秒为超时周期
			 */
			OnlineTask onlineTask = new OnlineTask("key"+i,System.currentTimeMillis(),30000);
			ScheduledFuture scheduledFuture=scheduledExecutorService.scheduleAtFixedRate(onlineTask, 1, 4, TimeUnit.SECONDS);
			futureCache.put("key"+i, scheduledFuture);
			taskCache.put("key"+i, onlineTask);
		}
		Thread.sleep(3000);
		
		/**
		 * 模拟一次心跳
		 */
		OnlineTask on = (OnlineTask)taskCache.get("key1");
		on.setLastUpdateTime(System.currentTimeMillis());
	}

}


/**
 * 用户在线判断类
 * @author yangcheng  
 * @date 2019年8月23日  
 * @version V1.0
 */
class OnlineTask implements Runnable{

	/**
	 * 毫秒
	 */
	private String key;
	private long lastUpdateTime = 0L;
	private int outTime = 1000;//毫秒
	
	/**
	 * 
	 * @param key  定时任务唯一标识
	 * @param lastUpdateTime  最后一次更新时间
	 * @param outTime  超时时间间隔
	 */
	public OnlineTask(String key, long lastUpdateTime, int outTime) {
		super();
		this.key = key;
		this.lastUpdateTime = lastUpdateTime;
		this.outTime = outTime;
	}

	private boolean isOutOfTime(){
		return System.currentTimeMillis()-lastUpdateTime > outTime; 
		
	}
	
	@Override
	public void run() {
		// 判断当前任务如果已经超时 则删除并停止当前定时任务的执行
		if(isOutOfTime()){
			
			TestScheduleTask.futureCache.remove(key).cancel(true);
			TestScheduleTask.taskCache.remove(key);
			System.out.println("key = "+key+" 超时下线成功......");
		}
	}

	public long getLastUpdateTime() {
		return lastUpdateTime;
	}

	public void setLastUpdateTime(long lastUpdateTime) {
		this.lastUpdateTime = lastUpdateTime;
	}

	public int getOutTime() {
		return outTime;
	}

	public void setOutTime(int outTime) {
		this.outTime = outTime;
	}
	
	
	
}